﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThresholdAssistant.Tools.Extensions
{
    /// <summary>
    /// 字符串类型扩展
    /// </summary>
    public static class StringExtensions
    {
        /// <summary>
        /// 得到字符串长度，一个汉字长度为2
        /// </summary>
        /// <param name="inputStr">参数字符串</param>
        /// <returns></returns>
        public static int GetLength(this string inputStr)
        {
            var tempLen = 0;
            if (string.IsNullOrEmpty(inputStr))
                return tempLen;

            var charArray = inputStr.ToCharArray();
            var asciiBytes = new ASCIIEncoding().GetBytes(inputStr);
            for (int i = 0; i < asciiBytes.Length; i++)
            {
                if (asciiBytes[i] == 63 && charArray[i] != '?')
                    tempLen += 2;
                else
                    tempLen += 1;
            }
            return tempLen;
        }

        /// <summary>
        /// 截取字符串中指定标签内的内容
        /// </summary>
        /// <param name="content">需要截取的字符串</param>
        /// <param name="start">开始标签</param>
        /// <param name="end">结束标签</param>
        /// <returns></returns>
        public static T GetContent<T>(this string content, string start, string end)
        {
            var value = content.GetContent(start, end);
            return value.ToObject<T>();
        }

        /// <summary>
        /// 截取字符串中指定标签内的内容
        /// </summary>
        /// <param name="content">需要截取的字符串</param>
        /// <param name="start">开始标签</param>
        /// <param name="end">结束标签</param>
        /// <returns></returns>
        public static string GetContent(this string content, string start, string end)
        {
            if (string.IsNullOrWhiteSpace(content))
                return "";

            content = content.Replace(@"\", "");
            content = content.Replace(@"\\n", "");
            var posStart = content.IndexOf(start);
            var posEnd = content.IndexOf(end);
            if (posStart < 0)
            {
                return "";
            }
            posStart += start.Length;
            return content.Substring(posStart, posEnd - posStart);
        }

        /// <summary>
        /// 转换成列表
        /// </summary>
        /// <param name="input">输入字符串</param>
        /// <returns></returns>
        public static List<string> ToList(this string input)
        {
            var list = new List<string>();
            if (!string.IsNullOrEmpty(input))
            {
                list.Add(input);
            }
            return list;
        }

        /// <summary>
        /// 转换成列表
        /// </summary>
        /// <param name="input">输入字符串</param>
        /// <returns></returns>
        public static string[] ToArray(this string input)
        {
            var list = new string[] { };
            if (!string.IsNullOrEmpty(input))
            {
                list = new string[] { input };
            }
            return list;
        }

        /// <summary>
        /// 微信ID转企微机器人编号
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string ToWorkSerialNo(this string content)
        {
            if (string.IsNullOrWhiteSpace(content))
            {
                return "";
            }
            return AesEncryptUtil.Encrypt(content, "9767EB94C541254FCE8ED83D02AD2496").ToUpper();
        }

        /// <summary>
        /// 企微机器人编号转ID
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string ToWorkId(this string content)
        {
            try
            {
                return AesEncryptUtil.Decrypt(content, "9767EB94C541254FCE8ED83D02AD2496");
            }
            catch { }
            return "";
        }

        /// <summary>
        /// 获取重试间隔的规则秒数列表(排序从小到大)
        /// </summary>
        /// <param name="retryDurationSeconds">重试间隔的规则秒数(多个使用','分割)</param>
        /// <returns></returns>
        public static async Task<IEnumerable<int>> GetRetryDurationSecondsListAsync(this string retryDurationSeconds)
        {
            IEnumerable<int> retryDurationSecondsList = new List<int>();
            if (!string.IsNullOrEmpty(retryDurationSeconds))
            {
                retryDurationSeconds = retryDurationSeconds.TrimStart(',').TrimEnd(',');
                retryDurationSecondsList = retryDurationSeconds.Split(',').Select(e => int.Parse(e));
            }
            return await Task.FromResult(retryDurationSecondsList);
        }

        /// <summary>
        /// 根据重试次数获取重试的延迟秒数
        /// </summary>
        /// <param name="retryDurationSecondsList">重试次数间隔的规则列表</param>
        /// <param name="retryCount">当前的重试次数</param>
        /// <returns></returns>
        public static async Task<int> GetRetryDelaySecondsAsync(this IEnumerable<int> retryDurationSecondsList, int retryCount)
        {
            if (retryDurationSecondsList == null | !retryDurationSecondsList.Any() || retryCount >= retryDurationSecondsList.Count())
                return 0;

            var retryDurationSecondsOrderList = retryDurationSecondsList.OrderBy(e => e).ToList();
            return await Task.FromResult(retryDurationSecondsOrderList[retryCount]);
        }

        /// <summary>
        /// 比较对象的大小
        /// </summary>
        /// <param name="condition">条件(= >= < <=等等)</param>
        /// <param name="propertyValue">对象值</param>
        /// <param name="conditionValue">条件值</param>
        /// <param name="ignoreCase">是否忽略大小写</param>
        /// <returns></returns>
        public static bool CompareSize(this string condition, string propertyValue, string conditionValue, bool ignoreCase = false)
        {
            var isSuccess = false;//是否成功
            if (string.IsNullOrEmpty(condition))
                return isSuccess;

            var isBool = propertyValue.IsBool();//是否是bool值
            if (isBool)
            {
                if (condition == "=")
                {
                    //bool类型可以比较等于
                    isSuccess = bool.Parse(propertyValue) == bool.Parse(conditionValue);
                }
                else if (condition != "!=")
                {
                    //bool类型可以比较不等于
                    isSuccess = bool.Parse(propertyValue) != bool.Parse(conditionValue);
                }
                else
                {
                    return isSuccess;
                }
            }
            else
            {
                var isNumber = propertyValue.IsNumber();//是否是数字类型
                if (isNumber)
                {
                    var propertyNumber = decimal.Parse(propertyValue);//比较值
                    var conditionNumber = decimal.Parse(conditionValue);//条件值
                    switch (condition)
                    {
                        case "="://等于
                            isSuccess = propertyNumber == conditionNumber;
                            break;
                        case ">"://大于
                            isSuccess = propertyNumber > conditionNumber;
                            break;
                        case ">="://大于等于
                            isSuccess = propertyNumber >= conditionNumber;
                            break;
                        case "<"://小于
                            isSuccess = propertyNumber < conditionNumber;
                            break;
                        case "<="://小于等于
                            isSuccess = propertyNumber <= conditionNumber;
                            break;
                        case "!="://不等于
                            isSuccess = propertyNumber != conditionNumber;
                            break;
                    }
                }
                else
                {
                    var isDateTime = propertyValue.IsDate();//是否是时间类型
                    if (isDateTime)
                    {
                        var propertyDateTime = DateTime.Parse(propertyValue);//比较值
                        var conditionDateTime = DateTime.Parse(conditionValue);//条件值
                        switch (condition)
                        {
                            case "="://等于
                                isSuccess = propertyDateTime == conditionDateTime;
                                break;
                            case ">"://大于
                                isSuccess = propertyDateTime > conditionDateTime;
                                break;
                            case ">="://大于等于
                                isSuccess = propertyDateTime >= conditionDateTime;
                                break;
                            case "<"://小于
                                isSuccess = propertyDateTime < conditionDateTime;
                                break;
                            case "<="://小于等于
                                isSuccess = propertyDateTime <= conditionDateTime;
                                break;
                            case "!="://不等于
                                isSuccess = propertyDateTime != conditionDateTime;
                                break;
                        }
                    }
                    else
                    {
                        var number = string.Compare(propertyValue, conditionValue, ignoreCase);//比较字符串的大小
                        switch (condition)
                        {
                            case "="://等于
                                isSuccess = number == 0;
                                break;
                            case ">"://大于
                                isSuccess = number > 0;
                                break;
                            case ">="://大于等于
                                isSuccess = number >= 0;
                                break;
                            case "<"://小于
                                isSuccess = number < 0;
                                break;
                            case "<="://小于等于
                                isSuccess = number <= 0;
                                break;
                            case "!="://等于
                                isSuccess = number != 0;
                                break;
                        }
                    }
                }

                if (condition == "in" || condition == "not in")
                {
                    var values = conditionValue.Split(',');
                    return condition == "in" ? values.Contains(propertyValue) : !values.Contains(propertyValue);
                }
            }
            return isSuccess;
        }
    }
}